﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Reflection;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel.DomainServices.Server;
using Microsoft.WindowsAzure.StorageClient;

namespace demo.Web.AzureTables

{

    /// <summary>
    /// Azure Table Storage (ATS) base class
    /// </summary>
    public partial class ATSEntityBase : TableServiceEntity
    {
 
        public ATSEntityBase()
        {
            this.SetEntityVersion();
        }


        #region VirtualFunctions - allow for overrides in subclasses with default implementation


        // default UID 
        protected virtual string MakeUniqueID()
        {
            string s;
            //s = string.Format("{0}_{1:10}_{2}", DateTime.UtcNow.ToString("yyyyMMdd"), DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());

            // shorter form
            string s1 = DateTime.UtcNow.ToString("yyyyMMdd");
            string s2 = DateTime.Now.Ticks.ToString("D8");         // ascending
            string s3 = (Guid.NewGuid().ToString());
            s3 = s3.Substring((s3.Length - 4));                     // take the last 4 digits

            s = string.Format("{0}_{1}_{2}", s1, s2, s3);
            return s;
        }


        protected virtual int SetEntityVersion(int version = 1)
        {
            this.EntityVersion = version;
            return this.EntityVersion;
        }

        #endregion

        #region CopyProperties - enable cloning of entities

        public static void CopyProperties(Object fromObj, Object toObj)
        {
            BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            CopyProperties(fromObj, toObj, flags);
        }

        public static void CopyProperties(Object fromObj, Object toObj, BindingFlags flags)
        {
            System.Type t = fromObj.GetType();
            PropertyInfo[] props = t.GetProperties(flags);
            foreach (PropertyInfo pi in props)
                pi.SetValue(toObj, pi.GetValue(fromObj, null), null);
        }

        #endregion


        #region COMPOSITE KEY methods

        public virtual string MakeID()
        {
            return MakeID(this.PartitionKey, this.RowKey);                    // assumes RowKey is immutable
        }

        public static string MakeID(string partitionKey, string uidKey)
        {
            return string.Format("{0}#{1}", partitionKey, uidKey);            // changed from RowKey - need an immutable key
        }


        /// <summary>
        /// split apart a composite key into partition/uid key components
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public static string[] ParseID(string ID)
        {
            string[] keyParts = new string[] { string.Empty, string.Empty };

            if (ID == null || ID.Length == 0)
                return keyParts;

            keyParts = ID.Split(new char[] { '#' });
            return keyParts;
        }
        #endregion



        public int EntityVersion { get; set; }
        public DateTime CreateDate { get; set; }
        public DateTime UpdateDate { get; set; }

    }
}